<?

/** 
* 2012-04-11  Obsługa datagrid AJAX 
* @author   Ben <mail@thecodefoundryltd.com>
* @version 2,1
* Dodane rzeczy:
* - obsłua kolumn po których nie sortuje
* - w wynikach zwracany wiersz z nr. lp. i jak np jesterm na 10 stronie a jest 10 elementow to pierwszys ma np. 100
* - zapytanie nie istotna kolejsnosc tabel w select. kolejnosc pobieram z argumentu sortable(tablica) wartosc pod kluczem nr_kolumny jezeli wystepuje wartosc to znaczy ze jest sortowanie
*  dzieki temu nie musze stosowac klucza eneable sortowanie
* - <a> w paginacji
* 
* Todo:
* - mozna dodac metode ktora automatycznie zbierze wszystkie wartosci z formularza i zwroci je w postaci hiddenow
* bylo by to wykorzystywane gdy chcialbym przeladowac strone i dalej miec te same wyniki paginacji
* 
* */
class MojeKlasy_SortableAjax
{
	/**
	 * Tryb debugowania
	 * @var bool
	 */
	public $debug=false;
    
    /**
    * Jakie będzie następne sortowanie. Na początku ma być sortowanie ASC
    * Potem przeciwne do obecnego. Wykorzystywane w liknu
    * @var string
    */
    private $order_future='ASC';
	
    /**
    * Tablica kolumn po ktorych sortuje, klucze: 
    * [nazwa] nazwa kolumny, 
    * [sortowanie] domyślnie true  czy mma po tej kolumnie sortować
    * @var array na poczatku bool FALSE
    */
	protected $sortable = false;

    /**
     * Array of options for the class
     * Dodałem order int numer kolumny po jakiej sortuje, order_type ASC/DESC
     * @access public
     * @var    array
     */
	protected $options = array(
        'results_per_page'              => 10,
        'max_pages_to_fetch'            => 1000000,
        'url'                           => '',
        'url_page_number_var'           => '*VAR*',
        'text_prev'                     => '&laquo; Prev',
        'text_next'                     => 'Next &raquo;',
        'text_first'                    => '&laquo; First',
        'text_last'                     => 'Last &raquo;',
        'text_ellipses'                 => '...',
        'class_ellipses'                => 'ellipses',
        'class_dead_links'              => 'dead-link',
        'class_live_links'              => 'live-link',
        'class_current_page'            => 'current-link',
        'class_ul'                      => 'pagination',
        'show_links_first_last'         => true,
        'show_links_prev_next'          => true,
        'show_links_first_last_if_dead' => true,
        'show_links_prev_next_if_dead'  => true,
        'max_links_between_ellipses'    => 7,
        'max_links_outside_ellipses'    => 2,
        'db_conn_type'                  => 'pdo',  /* Can be either: 'mysqli' or 'pdo' */
        'db_handle'                     => 0,
        'named_params'                  => false,
        'using_bound_params'            => false,
		'order'            				=> 1,
		'order_type'            		=> 'ASC',
		'class_live_links_order'        => null,
		'debug'							=> false // włączenie trybu debugowania
    );
    
    
    /**
     * An array of any errors
     *
     * @access protected
     * @var    array
     */
	protected $debug_log;
    
    
    /**
     * True if all good, false if theres a problem
     *
     * @access public
     * @var    bool
     */
	public $success = true;
    
    
    /**
     * The current page
     *
     * @access protected
     * @var    int
     */
	protected $current_page;
    
    
    /**
     * Zapytanie SQL wykonywane. w trybie debugowania public może być wypisane w konsoli
     * @var    string
     */
	public $query;
    
    
    /**
     * The total total number of links to render before showing the ellipses
     *
     * @access protected
     * @var    int
     */
	protected $number_of_links_before_showing_ellipses;
    
    
    /**
     * The PDO object - stored when users want to bind some params
     *
     * @access public
     * @var    string
     */
	protected $pdos;
    
    
    /**
     * The resultset of the query
     *
     * @access public
     * @var    resultset
     */
	public $resultset;
    
    
    /**
     * The total results of the query
     *
     * @access public
     * @var    int
     */
	public $total_results;
    
    
    /**
     * The total pages returned
     *
     * @access public
     * @var    int
     */
	public $total_pages;
    
    
    /**
     * Cała paginacja    Pierwszy < 1,2,3..133 > OStatni
     * Tworzone w funkcji build_links()
     * @access public
     * @var    string
     */
	public $links_html;

    /**
    * Tablica to tworzenie date grid nazwa kolumn po ktorych sortuje  w postaci linka
    * cała ta tablica jest wyswietlana w widoku  kazdy element to naglowek kolumn datagrid
    * @var array
    */
    public $links_html_order; 
    
    /**
     * Statyczny tymczasowy licznik numerowania
     * @var id
     */
    private $id_licznik=1 ;
    # bool pomocnicza jak pierwsze wyw. na strone to nie incrementuje, nastepne id_licznik zwiekszam
    private $id_licznik_pierwsze_wywolanie_strona=false ;
    
   /**
    * __construct(int $surrent_page, string $query, array $options)
    *
	* Class constructor
	*
	* @access  public
    * @param   int     $current_page  The number of the current page (Starts at 1)
    * @param   string  $query         The query to run on the database
    * @param   array   $options       An array of options
    * @param   array   $sortable      tablica kolumn po ktorych sortuje, jej wartosc to nazwa
	* @return  void
	*/
	public function __construct($current_page = 1, $query = '', $options = null, $sortable=null )
	{
		// echo $current_page;exit;
        if( $current_page  !=1 )
        {
        	$this->id_licznik=($current_page*$options['results_per_page'])+1;
        }
          
       //echo $this->id_licznik.'TTTTTTTT'.$current_page.'TTTT'.$options['results_per_page'];
       $this->run($current_page, $query, $options, $sortable);    	
	}
    
    
    /**
    * run(int $surrent_page, string $query, array $options)
    *
	* Run the class
	*
	* @access  public
    * @param   int     $current_page  The number of the current page (Starts at 1)
    * @param   string  $query         The query to run on the database
    * @param   array   $options       An array of options
	* @return  void
	*/
    public function run( $current_page = 1, $query = '', $options = null, $sortable= null )
    {
    	$this->sortable=$sortable;
        /*
         * Set the current page
         */
        $this->current_page = $current_page;
        
        /*
         * Set the query to run
         */
        $this->query = $query;
        
        /*
         * Populate the options array
         */
        if( $this->set_options($options) == true )
        {
	        # przy pierwszym uruchomieniu nie wejdzie (order getem nie przekazuje i nie ustawiam w argumencie option)
	        if($this->options['order_type']=='ASC')
	        {
	            $this->order_future= 'DESC';
	        }
	        
	        if( $this->options['order_type'] == 'DESC' )
	        {               
	            $this->order_future= 'ASC';
	        }
        
            /*
             * Add any extra code into the query
             */
            $this->prepare_query();
            
            /*
             * Execute the SQL
             */
            $this->excecute_query();
            
            /*
             * Calculate the total number of pages
             */
            $this->calculate_number_of_pages();
            
            /*
             * Work out the total number of pages before an ellipses is shown
             */
            $this->calculate_max_pages_before_ellipses();
            
            /*
             * Build the HTML to output
             */
            $this->build_links();
            
            /*
             * Set success to true
             */
            $this->success = true;
        }
        else
        {
            /*
             * Show the debug log to the user
             */
            $this->debug();
            
            /*
             * Set success to false
             */
            $this->success = false;
        }
        
    }
    
    
    /**
    * set_options(array $options)
    *
	* Apply any options that have been provided
	*
	* @access  protected
    * @param   array   $options  An array of options
	* @return  void
	*/
    protected function set_options($options = null)
    {
        if(!empty($options))
        {
            foreach($options as $key => $value)
            {
                if(array_key_exists($key, $this->options))
                {
                    $this->options[$key] = $value;
                }
                else
                {
                    $this->debug_log[] = 'Attempted to add setting \''.$key.'\' with the value \''.$value.'\' - option does not exist';
                }
            }
        }
        
        /*
         * Check to make sure we've been given a db handle
         */
        if(trim($this->options['url']) == '')
        {
            $this->debug_log[] = 'You have not provided a URL - please pass one with the option \'url\'';
            return false;
        }
        
        /*
         * Check to make sure we've been given a db handle
         */
        if(is_int($this->options['db_handle']) && $this->options['db_handle'] == 0)
        {
            $this->debug_log[] = 'You have not provided a DB Handle (Object) - please pass one with the option \'db_handle\'';
            return false;
        }
        
        /*
         * Check to make sure 'max_links_between_ellipses' is an odd number
         */
        if(!($this->options['max_links_between_ellipses'] & 1))
        {
            $this->debug_log[] = 'Setting \'max_links_between_ellipses\' has been set with the value \''.$this->options['max_links_between_ellipses'].'\' - This number must be an odd number';
            return false;
        }
        
        /*
         * Check to make sure the page number variable is in the URL
         */
        $page_number_var_position = strpos($this->options['url'], $this->options['url_page_number_var']);
        if($page_number_var_position === false)
        {
            $this->debug_log[] = 'You have not placed the variable in your URL that will be replaced with the page number - please add this variable where required: <strong>'.$this->options['url_page_number_var'].'<strong>';
            return false;
        }
        
        /*
         * If the checks have passed, return true
         */
        return true;
    }
    
    
    /**
    * prepare_query(void)
    *
	* Prepares the query to be run with the found rows and start/end limits
	*
	* @access  protected
	* @return  void
	*/
    protected function prepare_query( )
    {
        /*
         * Add SQL_CALC_FOUND_ROWS (If it's not there) for finding out total amount of results later on
         */
        if(substr($this->query, 0, 26) != 'SELECT SQL_CALC_FOUND_ROWS')
        {
            $this->query = substr_replace($this->query, 'SELECT SQL_CALC_FOUND_ROWS', 0, 6);
        }
        
        # PD 2012+03+29 dodanie sotrowania
        if($this->options['order'] && $this->options['order_type'])
        {
    	    $this->query=$this->query.' order by '.$this->options['order']." ".$this->options['order_type'];
        }
        
    	if($this->debug)
    	{
    		echo "<br>zapytka ".$this->query.'<br>';
    	}
    	
    	
        /*
         * Add our start/end limit
         */
        if($this->current_page == 1)
        {
            $this->query .= ' LIMIT 0, '.$this->options['results_per_page'];
        }
        else
        {
            $this->query .= ' LIMIT '.(($this->current_page - 1) * $this->options['results_per_page']).', '.$this->options['results_per_page'];
        }
    }
    
    
    /**
    * Wykonywanie zapytania excecute_query(void)
    *
	* Run's the query against the database
	*
	* @access  protected
	* @return  void
	*/
    protected function excecute_query()
    {
    	
        if($this->options['db_conn_type'] == 'mysqli')
        {
            /*
             * Execute using MySQLi
             */
            $this->resultset = $this->options['db_handle']->query($this->query);
            
            /*
             * Get the total results with FOUND_ROWS()
             */
            $count_rows = $this->options['db_handle']->query('SELECT FOUND_ROWS();');
            $found_rows = $count_rows->fetch_assoc();
            $this->total_results = $found_rows['FOUND_ROWS()'];
        }
        elseif($this->options['db_conn_type'] == 'pdo')
        {	
        	
			if($this->options['using_bound_params'] == false)
			{
				/*
				 * Execute using PDO - not using bindParams
				 */
				$pdos = $this->options['db_handle']->prepare($this->query);
				
				/*
				 * Use plain method or bind some named params
				 *
				 * Using alternate styles to avoid any errors with empty arrays
				 */
				if($this->options['named_params'] == false)
				{
					$pdos->execute();
				}
				else
				{
					$pdos->execute($this->options['named_params']);
				}
				
				$this->resultset = $pdos;
				
				/*
				 * Get the total results with FOUND_ROWS()
				 */
				$pdos_fr = $this->options['db_handle']->prepare("SELECT FOUND_ROWS();");
				$pdos_fr->execute();
				$pdos_fr_result = $pdos_fr->fetch(PDO::FETCH_ASSOC);
				$this->total_results = $pdos_fr_result['FOUND_ROWS()'];
			}
			else
			{
				/*
				 * Excecute using PDO, but pause for binding params
				 */
				$this->pdos = $this->options['db_handle']->prepare($this->query);
			}
        }
        else
        {
            /*
             * An unknown DB connection type has been set
             */
            $this->debug_log[] = 'You have selected a \'db_conn_type\' of \''.$this->options['db_conn_type'].'\' - this method is not supported';
        }
    
    }
    
    /**
    * bind(standard params)
    *
	* Bind params to the query
	*
	* @access  public
	* @param   multi   Typical bindParam attr
	* @return  void
	*/
	public function bindParam($a = null, $b = null, $c = null, $d = null, $e = null)
	{
		$this->pdos->bindParam($a, $b, $c, $d, $e);
	}
    
    
    /**
    * execute(void)
    *
	* Continues the execution of the query after binding params
	*
	* @access  public
	* @return  void
	*/
	public function execute()
	{
		$this->pdos->execute();
		
		$this->resultset = $this->pdos;
		
	
		/*
		 * Get the total results with FOUND_ROWS()
		 */
		$pdos_fr = $this->options['db_handle']->prepare("SELECT FOUND_ROWS();");
		$pdos_fr->execute();
		$pdos_fr_result = $pdos_fr->fetch(PDO::FETCH_ASSOC);
		$this->total_results = $pdos_fr_result['FOUND_ROWS()'];
		
		/*
		 * Calculate the total number of pages
		 */
		$this->calculate_number_of_pages();
		
		/*
		 * Work out the total number of pages before an ellipses is shown
		 */
		$this->calculate_max_pages_before_ellipses();
		
		/*
		 * Build the HTML to output
		 */
		$this->build_links();
		
		/*
		 * Set success to true
		 */
		$this->success = true;
	}
    
    
    /**
    * calculate_number_of_pages(void)
    *
	* Calculates how many pages there will be
	*
	* @access  protected
	* @return  void
	*/
    protected function calculate_number_of_pages()
    {
        if(ceil($this->total_results / $this->options['results_per_page']) > $this->options['max_pages_to_fetch'])
        {
            $this->total_pages = $this->options['max_pages_to_fetch'];
        }
        else
        {
            $this->total_pages = ceil($this->total_results / $this->options['results_per_page']);
        }
    }
    
    
    /**
    * calculate_max_pages_before_ellipses(void)
    *
	* Calculates the number of links to show before showing an ellipses
	*
	* @access  protected
	* @return  void
	*/
    protected function calculate_max_pages_before_ellipses()
	{
		$this->number_of_links_before_showing_ellipses = $this->options['max_links_between_ellipses'] + ($this->options['max_links_outside_ellipses'] * 2);
	}
    
    
    /**
    * build_link_url(int $page_number)
    *
	* Builds the URL to insert in links
	*
	* @access  protected
    * @param   int     $page_number  The page number to insert into the link
	* @return  string                The built URL
	*/
    protected function build_link_url( $page_number )
    {
    	
        return str_replace($this->options['url_page_number_var'], $page_number, $this->options['url']);
    }
    
     
    /**
     * Budowanie atrybutów jakie benda w linku wywylanym ajaxem przykladowe atryb to order, page...
     * przesyłam atrybuty i potem pobieram ich wartosc przez jq jest prosciej niz robijac link
     * @author DP 02-04-2012 
     * @param int $page_number
     */
    protected function  build_link_sortable_attrybuty( $page_number )
    {
    	return "page=".$page_number."&";
    }
    
    /**
    * get_current_or_normal_class(int $page_number)
    *
	* Returns the live link class, or link link and current page class
	*
	* @access  protected
    * @param   int     $page_number  The page number to insert into the link
	* @return  string                The class to use
	*/
    protected function get_current_or_normal_class($page_number)
    {
        if($page_number == $this->current_page)
        {
            return $this->options['class_live_links'].' '.$this->options['class_current_page'];
        }
        else
        {
            return $this->options['class_live_links'];
        }
    }
    
    
    /**
    * Tworzenie całej paginacji    Pierwszy < 1,2,3..133 > OStatni    w postaci HTNL
    * I przechowanie jej w $this->links_html
	* @access  protected
	* @return  void
	*/
    protected function build_links()
    {
        /*
         * Start the UL
         */
        $this->links_html = '<ul class="'.$this->options['class_ul'].'">'.PHP_EOL;
        
        $this->build_links_first_prev();
        
        /*
         * Build our main links
         */
        if($this->total_pages <= $this->number_of_links_before_showing_ellipses)
        {
            $this->build_links_skip_all_ellipses();
        }
        else
        {
            /*
             * We have enough links to show the ellipses, so run through other method
             */
            if($this->current_page <= (($this->options['max_links_between_ellipses'] + $this->options['max_links_outside_ellipses'])) - 2)
			{
                $this->build_links_skip_first_ellipses();
            }
            elseif($this->current_page > (($this->options['max_links_between_ellipses'] + $this->options['max_links_outside_ellipses']) - 2) && $this->current_page < (($this->total_pages - ($this->options['max_links_between_ellipses'] + $this->options['max_links_outside_ellipses']) + 1) + 2))
            {
                $this->build_links_dont_skip_ellipses();
            }
			else
			{
                $this->build_links_skip_last_ellipses();
			}
        }
        
        $this->build_links_next_last();
        $this->build_links_order();

         /*
         * Close the UL
         */
        $this->links_html .= '</ul>'.PHP_EOL;
    }
    
    
    /**
    * Budowanie częsic calej paginacji: Pierwszy, następny 
	* Builds (if required) the First/Prev links
	*
	* @access  protected
	* @return  void
	*/
    protected function build_links_first_prev()
    {
        # wybrano sortowanie po kolumnie wiec paginacja musi to uwzględnic
        $dodatkowy_adres_sortable=null;
        if( $this->options['order']&& $this->options['order_type'] )
        {
         $dodatkowy_adres_sortable='&order='.$this->options['order'].'&type='.$this->options['order_type'];
        }
        /*
         * The 'First' link
         */
        if($this->options['show_links_first_last'] == true)
        {
            if($this->current_page == 1 && $this->options['show_links_first_last_if_dead'] == true)
            {
                $this->links_html .= '<a href="javascript:void(0);" class="'.$this->options['class_dead_links'].' paginate_first ">'.$this->options['text_first'].'</a>'.PHP_EOL;
            }
            elseif($this->current_page != 1)
            {
            	# przeniesienie na pierwszą strone
                $this->links_html .= '<a href="javascript:void(0);"  class="'.$this->options['class_live_links'].' paginate_first " href="'.$this->build_link_url(1).$dodatkowy_adres_sortable.'" atrybuty="page=1'.$dodatkowy_adres_sortable.'">'.$this->options['text_first'].'</a>'.PHP_EOL;
            }
        }
        
        /*
         * The 'Previous' link
         */
        if($this->options['show_links_prev_next'] == true)
        {
            if($this->current_page == 1 && $this->options['show_links_prev_next_if_dead'] == true)
            {
                $this->links_html .= '<a href="javascript:void(0);" class="'.$this->options['class_dead_links'].' paginate_first ">'.$this->options['text_prev'].'</a>'.PHP_EOL;
            }
            elseif($this->current_page != 1)
            {
            	$curene_page_1=$this->current_page-1;
            	# przeniesienie na ostatnia strone
                $this->links_html .= '<a  href="javascript:void(0);" class="'.$this->options['class_live_links'].' paginate_first " href="'.$this->build_link_url($this->current_page - 1).$dodatkowy_adres_sortable.'" atrybuty="page='.$curene_page_1.$dodatkowy_adres_sortable.'">'.$this->options['text_prev'].'</a>'.PHP_EOL;
            }
        }
    }
    
    
    /**
    * loop_through_links(int $start, int $finish)
    * WYNIKA Z TEGO ZE BUDUJUE PAGINACJE 1,2,3..
	* Loops through a given range of numbers and add's then as links in the html
	*
	* @access  protected
    * @param   int     $start   The number to start looping
    * @param   int     $finish  The number to finish looping
	* @return  void
	*/
    protected function loop_through_links($start, $finish)
    {
        # PD wybrano sortowanie po kolumnie wiec paginacja musi to uwzględnic
        $dodatkowy_adres_sortable=null;
        if( $this->options['order']&& $this->options['order_type'] )
        {
         $dodatkowy_adres_sortable='&order='.$this->options['order'].'&type='.$this->options['order_type'];
        }
        
        $counter = $start;
        while($counter <= $finish)
        {
            $this->links_html .= '<a href="javascript:void(0);"  class="'.$this->get_current_or_normal_class($counter).' pagination_number " atrybuty="page='.$counter.$dodatkowy_adres_sortable.'">'.$counter.'</a>'.PHP_EOL;
            
            $counter++;
        }
    }
    
    
    /**
    * add_ellipses(void)
    *
	* Add's an ellipses to the html
	*
	* @access  protected
	* @return  void
	*/
    protected function add_ellipses()
    {
        $this->links_html .= '<a href="javascript:void(0);"  class="'.$this->options['class_ellipses'].'">'.$this->options['text_ellipses'].'</a>'.PHP_EOL;
    }
    
    
    /**
    * build_links_skip_all_ellipses(void)
    *
	* Add all links, with no ellipses at all
	*
	* @access  protected
	* @return  void
	*/
    protected function build_links_skip_all_ellipses()
    {
        /*
         * If there's not enough links to have an ellipses in the set, just run through them all
         */
        $this->loop_through_links(1, $this->total_pages);
    }
    
    
    /**
    * build_links_skip_first_ellipses(void)
    *
	* Add all links, without the first ellipses
	*
	* @access  protected
	* @return  void
	*/
    protected function build_links_skip_first_ellipses()
    {
        /*
         * Type 1 - skipping the first ellipses due to being low in the current page number
         */
        $this->loop_through_links(1, ($this->options['max_links_between_ellipses'] + $this->options['max_links_outside_ellipses']));
        
        $this->add_ellipses();
        
        $this->loop_through_links((($this->total_pages - $this->options['max_links_outside_ellipses']) + 1), $this->total_pages);
    }
    
    
    /**
    * build_links_dont_skip_ellipses(void)
    *
	* Add all links, with both sets of ellipses
	*
	* @access  protected
	* @return  void
	*/
    protected function build_links_dont_skip_ellipses()
    {
        /*
         * Type 2 - Current page is between both sets of ellipses
         */
        $this->loop_through_links(1, $this->options['max_links_outside_ellipses']);
        
        $this->add_ellipses();
        
        $before_after = (($this->options['max_links_between_ellipses'] - 1) / 2);
        
        $this->loop_through_links(($this->current_page - $before_after), ($this->current_page + $before_after));
        
        $this->add_ellipses();
        
        $this->loop_through_links((($this->total_pages - $this->options['max_links_outside_ellipses']) + 1), $this->total_pages);
    }
    
    
    /**
    * build_links_dont_skip_ellipses(void)
    *
	* Add all links, without the last ellipses
	*
	* @access  protected
	* @return  void
	*/
    protected function build_links_skip_last_ellipses()
    {
        /*
         * Type 3 - skipping the last ellipses due to being high in the current page number
         */
        $this->loop_through_links(1, $this->options['max_links_outside_ellipses']);
        
        $this->add_ellipses();
        
        $this->loop_through_links((($this->total_pages - ($this->options['max_links_between_ellipses'] + $this->options['max_links_outside_ellipses'])) + 1), $this->total_pages);
    }
    
    
    /**
    * build_links_next_last(void)
    *
	* BUDUJE the Next/Last links
	*
	* @access  protected
	* @return  void
	*/
    protected function build_links_next_last()
    {
        # PD wybrano sortowanie po kolumnie wiec paginacja musi to uwzględnic
        $dodatkowy_adres_sortable=null;
        if( $this->options['order']&& $this->options['order_type'] )
        {
         $dodatkowy_adres_sortable='&order='.$this->options['order'].'&type='.$this->options['order_type'];
        }
        
        /*
         * The 'Next' link
         */
        if($this->options['show_links_prev_next'] == true)
        {
            if($this->current_page == $this->total_pages && $this->options['show_links_prev_next_if_dead'] == true)
            {
                $this->links_html .= '<a href="javascript:void(0);"  class="'.$this->options['class_dead_links'].'">'.$this->options['text_next'].'</a>'.PHP_EOL;
            }
            elseif($this->current_page != $this->total_pages)
            {
            	$current_page_plus_jeden=$this->current_page + 1;
                $this->links_html .= '<a  href="javascript:void(0);"  class="'.$this->options['class_live_links'].' paginate_next " href="'.$this->build_link_url($this->current_page + 1).$dodatkowy_adres_sortable.'" atrybuty="page='.$current_page_plus_jeden.$dodatkowy_adres_sortable.'">'.$this->options['text_next'].'</a>'.PHP_EOL;
            }
        }
        
        /*
         * The 'Last' link
         */
        if($this->options['show_links_first_last'] == true)
        {
            if($this->current_page == $this->total_pages && $this->options['show_links_first_last_if_dead'] == true)
            {
                $this->links_html .= '<a href="javascript:void(0);" class="'.$this->options['class_dead_links'].'">'.$this->options['text_last'].'</a>'.PHP_EOL;
            }
            elseif($this->current_page != $this->total_pages)
            {
                $this->links_html .= '<a href="javascript:void(0);" class="'.$this->options['class_live_links'].' paginate_next "  atrybuty="page='.$this->total_pages.$dodatkowy_adres_sortable.'">'.$this->options['text_last'].'</a>'.PHP_EOL;
            }
        }
    }
    
  /**
    * build_links_order
    * @author dp
	* Builds (if required) the Next/Last links
	*
	* @access  protected
	* @var array $order_array array(order,order_type,name)
	* @return  void
	*/
    protected function build_links_order( )
    {    
    	# buduję nazwe kolumny ktora zostala wybrana do sortowania	
        foreach($this->sortable as $key=>$vartosc)
        {
            $class_live_links_order= null;
            if($this->options['class_live_links_order'])
            {
            	$class_live_links_order= $this->options['class_live_links_order'];	
            }
            
                # jak jest to kliknieta to w nazwie stylu dodaje asc albo desc to po czym sortuje
                # css juz potem narysuje szczalke 
                $selected_order=null;
                if( $this->options['order']==$key )
                {
                    $selected_order=' '.$this->options['order_type'].' ';     
                }
                
                #
                # Budowanie nazwy klasy wykorzystanej w nagłówku do sottowania. Jeżeli w parametrze ustawiłem sortable uswilem klucz 'wartosc' na false po kolumnie nie bedzie mozna sortowac
                #
                $czy_sortowanie_wlaczone='ajax_sortable';
               
                # nie chce sortowac po tej kolumnie
                if( empty($vartosc['nr_kolumny']) )
                {
                	$this->links_html_order[] .= '<span class="'.$class_live_links_order.'" >'.$vartosc['nazwa'].'</span>'.PHP_EOL;
                }
                else // nie buduje <a bo bedzie to nagłowek kolumny bez sortowania
                {
                	$clasa_css='class="'.$class_live_links_order.' '.$selected_order.' ajax_sortable "';
             		$sufix='&order='.(int)$vartosc['nr_kolumny'].'&type='.$this->order_future;
             
            		# dodnie dodatkowego atrybutu o nazwie atrybut jego wartość zostanie bezpośrednio doklejona do wywołania ajax nie musze rozbijac linka albo co innego
             		$this->links_html_order[] .= '<a '.$clasa_css.' href="javascript:void(0);" atrybuty="page=1'.$sufix.'" >'.$vartosc['nazwa'].'</a>'.PHP_EOL;
                }    
        }
    }
    
    /**
    * debug(void)
    *
	* Show the debug log
	*
	* @access  public
	* @return  void
	*/
    public function debug()
    {
        echo '<pre>';
        echo '<p>There appears to be a problem with the Paginate() options:</p>';
        print_r($this->debug_log);
        echo '</pre>';
    }
    
    public function test()
    {
     echo 'dziala';
    }
    
    /**
     * @author PD 2012-04-06
     * Zwraca aktualny numer wiersza np. na 10 stronie z 10 elementami wyświetlanymi dla pierwszego wywołania zwrówci 100
     * @return int
     */
    public function idNumber()
    {
    	# włączyć w trybie degugowania
    	//$wynik="Lb elementow na strone:".$this->current_page.",który element".$this->id_licznik;
    	if($this->id_licznik_pierwsze_wywolanie_strona)
    	{
    		$this->id_licznik++;	
    	}
    	
    	$this->id_licznik_pierwsze_wywolanie_strona=true;
    	return $this->id_licznik;
    }
    
    /**
     * Ajaxowe śmieci wymagane wyswietlenei aby ajax dziala. Odpalam metode w samym widoku 
     * Moga zostac napisane w widoku, albo automatycznie wyswietlac je z poziomu paginacji
     * Uwaga nie może być ona odpalana za każdym wywołaniem paginacji tzn z poziomu ajaxa dodawana bo wtedy bedzie jej wywolan przybywac
     */
    public function initAjax()
    {
    	?>
    	<script>
		$().ready(function() { 
		
		  //ajax_sortable sortowanie; pagination_number - 1,2,3; paginate_next >>,Ostatni; paginate_first <<, Pierewszy
		  $('.ajax_sortable, .pagination_number, .paginate_next, .paginate_first').live('click', function() 
		   {
			  $("#preloader").css("display","block");
				  //$(this).css({'color':'red'}).html('You clicked me');
				  var value= '&'+$(this).attr('atrybuty');
			  		
			  	  $.ajax({
			          type: "POST",
			          url: "<?php echo $this->options['url']; ?>", 
			          data: "etap=ajax"+value,
		
			          success: function(html){
			                                    $("#tabella_paginacja").html(html);
			                                    $("#preloader").css("display","none");
			                                 }
			        });
			});
		});  
		
		</script>
		<?php 
    }

}


?>